package com.zdkj.subway.stm.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.annotation.Inner;
import com.zdkj.subway.stm.dto.out.SwStOneWayStatisticsDTO;
import com.zdkj.subway.stm.entity.SwStOneWayStatistics;
import com.zdkj.subway.stm.service.SwStOneWayStatisticsService;
import com.zdkj.subway.stm.util.DateUtilStm;
import com.zdkj.subway.stm.util.LocalDateConverter;
import com.zdkj.subway.stm.util.LocalDateTimeConverter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * 单程票流失率统计表
 *
 * @author cui_com
 * @date 2020-08-21 15:39:25
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swstonewaystatistics")
@Api(value = "swstonewaystatistics", tags = "单程票流失率统计表管理")
public class SwStOneWayStatisticsController {

    private final SwStOneWayStatisticsService swStOneWayStatisticsService;

    /**
     * 按年月查询各线路
     *
     * @param dateTime 日期
     * @return
     */
    @ApiOperation(value = "按年月查询各线路", notes = "按年月查询各线路(格式:2020-08-20)")
    @GetMapping("/page/detail/{dateTime}")
    public R getSwStOneWayStatistics(@PathVariable String dateTime) {
        return R.ok(swStOneWayStatisticsService.list(Wrappers.<SwStOneWayStatistics>query()
                .select("id,line_code,line_name,date_time,start_time,end_time,pre_month_amount,cur_month_delivery,cur_month_recovery," +
                        "cur_month_amount,cur_month_lost,on_way_passenger_amount,create_time,del_flag," +
                        "CASE WHEN on_way_passenger_amount = 0 THEN '' ELSE truncate(cur_month_lost  / on_way_passenger_amount,2) END AS cur_month_lost_percent")
                .orderByDesc("date_time").lambda()
                .eq(SwStOneWayStatistics::getDateTime, dateTime)));
    }

    /**
     * 分页查询
     *
     * @param swStOneWayStatistics 日期
     * @return
     */
    @ApiOperation(value = "按年月查询各月份", notes = "按年月查询各月份")
    @GetMapping("/page")
    public R getSwStOneWayStatisticsPage(Page page, SwStOneWayStatistics swStOneWayStatistics) {
        List<String> dateConditionhs;
        String startTime = "";
        String endTime = "";
        if(CollectionUtil.isNotEmpty(swStOneWayStatistics.getDates1())){
            if(swStOneWayStatistics.getDates1().get(0)!=null&&!"".equals(swStOneWayStatistics.getDates1().get(0))){
                dateConditionhs = swStOneWayStatistics.getDates1();
                startTime = dateConditionhs.get(0);
                endTime = dateConditionhs.get(1);
            }
        }
        return R.ok(swStOneWayStatisticsService.calcListPage(page, startTime,endTime));
    }

    /**
     * 定时器每天调用，生成前一天的当月数据(跨月就会计算上个月)
     *
     * @return
     */
    @Inner
    @ApiOperation(value = "计算本月的统计数据", notes = "计算本月的统计数据")
    @PostMapping("/calc")
    public R insertOrUpdate() {
        String dateTime = DateUtilStm.asPreDateString(LocalDateTime.now());
        List<SwStOneWayStatisticsDTO> list = swStOneWayStatisticsService.calcData(dateTime);
        List<SwStOneWayStatistics> listUpdate = new ArrayList<>();

        list.forEach(dto -> {
            //是否已存在(每天都执行，同一个月就自动更新数据)
            SwStOneWayStatistics db = swStOneWayStatisticsService.getOne(Wrappers.<SwStOneWayStatistics>query().lambda()
                .eq(SwStOneWayStatistics::getDateTime,dto.getDateTime())
                .eq(SwStOneWayStatistics::getLineCode,dto.getLineCode()));
            if(null == db){
                db = new SwStOneWayStatistics();
            }
            BeanUtils.copyProperties(dto,db);
            db.setDelFlag(CommonConstants.STATUS_NORMAL);
            listUpdate.add(db);
        });
        return R.ok(swStOneWayStatisticsService.saveOrUpdateBatch(listUpdate));
    }



    /**
     * 计算本月的统计数据
     * 统计周期：上个月26日到本月25日之间的数据
     * @return
     */
    @ApiOperation(value = "计算上月26日到本月25日的统计数据", notes = "计算上月26日到本月25日的统计数据")
    @PostMapping("/calcOneWayStatistics")
    public R calcOneWayStatistics(@RequestParam(value = "startTime") String startTime,@RequestParam(value = "endTime") String endTime) {
        List<SwStOneWayStatisticsDTO> list = swStOneWayStatisticsService.calcDatas(startTime,endTime);
        String startTimeD = DateUtilStm.getNextDay(startTime,-1,"yyyy-MM-dd");
        for (SwStOneWayStatisticsDTO item : list) {
            SwStOneWayStatisticsDTO oneWayStatisticsLastday = swStOneWayStatisticsService.calcPreMonthAmount(startTimeD,item.getLineCode());
            if(oneWayStatisticsLastday!=null)
                item.setPreMonthAmount(oneWayStatisticsLastday.getPreMonthAmount());
            else
                item.setPreMonthAmount(0);
            SwStOneWayStatisticsDTO oneWayStatisticsToday = swStOneWayStatisticsService.calcPreMonthAmount(endTime,item.getLineCode());
            if(oneWayStatisticsToday!=null)
                item.setCurMonthAmount(oneWayStatisticsToday.getCurMonthAmount());
            else
                item.setCurMonthAmount(0);
        }
        //List<SwStOneWayStatistics> listSave = new ArrayList<>();
        List<SwStOneWayStatistics> listUpdate = new ArrayList<>();
        boolean flag = true;
        for (SwStOneWayStatisticsDTO dto : list) {
            //是否已存在(每天都执行，同一个月就自动更新数据)
            SwStOneWayStatistics db = swStOneWayStatisticsService.getOne(Wrappers.<SwStOneWayStatistics>query().lambda()
                    .eq(SwStOneWayStatistics::getStartTime,startTime)
                    .eq(SwStOneWayStatistics::getEndTime,endTime)
                    .eq(SwStOneWayStatistics::getLineCode,dto.getLineCode()));
            if(db ==null){
                db = new SwStOneWayStatistics();
                BeanUtils.copyProperties(dto,db);
                db.setDelFlag(CommonConstants.STATUS_NORMAL);
                db.setStartTime(DateUtilStm.LocalDateToString(startTime));
                db.setEndTime(DateUtilStm.LocalDateToString(endTime));
                flag = swStOneWayStatisticsService.save(db);
                if(flag) {
                    db.setLineCode(dto.getLineCode());
                    swStOneWayStatisticsService.updateById(db);
                }else{
                    R.failed("统计生成失败");
                }
                //listSave.add(db);
            }else {
                BeanUtils.copyProperties(dto,db,new String[]{"id","onWayPassengerAmount"});
                db.setDelFlag(CommonConstants.STATUS_NORMAL);
                db.setStartTime(DateUtilStm.LocalDateToString(startTime));
                db.setEndTime(DateUtilStm.LocalDateToString(endTime));
                listUpdate.add(db);
            }
        }
        /*if(CollectionUtils.isNotEmpty(listSave)){
            flag = swStOneWayStatisticsService.saveBatch(listSave);
            if(!flag)
                R.failed("统计生失败");
        }*/
        if(CollectionUtils.isNotEmpty(listUpdate)){
            flag = swStOneWayStatisticsService.updateBatchById(listUpdate);
            if(!flag)
                R.failed("统计生成失败");
        }
        return R.ok(flag,"统计生成成功");
    }

    @ApiOperation(value = "修改明细数据", notes = "修改明细数据")
    @PutMapping("/updateDetail")
    public R updateDetail(@RequestBody List<SwStOneWayStatistics> detailEditData){
        return R.ok(swStOneWayStatisticsService.updateBatchById(detailEditData));
    }


    @ApiOperation(value = "导出单程票流失率统计", notes = "导出单程票流失率统计")
    @GetMapping("/export")
    @SysLog("导出单程票流失率统计")
    public void exportExcel(SwStOneWayStatistics swStOneWayStatistics, HttpServletResponse response) throws IOException {
        List<String> dateConditionhs;
        String startTime = "";
        String endTime = "";
        if(CollectionUtil.isNotEmpty(swStOneWayStatistics.getDates1())){
            if(swStOneWayStatistics.getDates1().get(0)!=null&&!"".equals(swStOneWayStatistics.getDates1().get(0))){
                dateConditionhs = swStOneWayStatistics.getDates1();
                startTime = dateConditionhs.get(0);
                endTime = dateConditionhs.get(1);
            }
        }
        IPage page = new Page<SwStOneWayStatistics>();
        page.setSize(-1);
        IPage<SwStOneWayStatisticsDTO> pageData = swStOneWayStatisticsService.calcListPage(page,startTime,endTime);
        List<SwStOneWayStatisticsDTO> swStOneWayStatisticsList = new ArrayList<>();
        if(null != pageData.getRecords()){
            swStOneWayStatisticsList = pageData.getRecords();
        }
        String fileName = URLEncoder.encode("单程票流失率统计", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");
        EasyExcel.write(response.getOutputStream(), SwStOneWayStatisticsDTO.class).registerConverter(new LocalDateTimeConverter())
                .registerConverter(new LocalDateConverter()).sheet("单程票流失率统计").doWrite(swStOneWayStatisticsList);
    }
}
